import json

from django.db import models
from django.db.models.fields import DateField, DateTimeField
from django.db.models.fields.related import ManyToManyField


class BaseModel(models.Model):
    class Meta:
        abstract = True

    def toDict(self, fields=None, exclude=None):
        data = {}
        for f in self._meta.concrete_fields + self._meta.many_to_many:
            value = f.value_from_object(self)
            if fields and f.name not in fields:
                continue
            if exclude and f.name in exclude:
                continue
            if isinstance(f, ManyToManyField):
                value = [i.id for i in value] if self.pk else None
            elif isinstance(f, DateTimeField):
                value = value.strftime('%Y-%m-%d %H:%M:%S') if value else None
            elif isinstance(f, DateField):
                value = value.strftime('%Y-%m-%d') if value else None
            data[f.name] = value
        return data

    def toJSON(self):
        return json.dumps(self.toDict(), ensure_ascii=False).encode('utf-8').decode()


class Person(BaseModel):
    name = models.CharField(max_length=128)
    age = models.IntegerField()
    grade = models.IntegerField()

    def __str__(self):
        return self.name


class Group(BaseModel):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):
        return self.name


class Membership(BaseModel):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()        # 进组时间
    invite_reason = models.CharField(max_length=64)  # 邀请原因
